home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-08-07 | 12.3 KB | 408 lines | [TEXT/MMCC] |
- /************************************************************************/
- /* Project...: Standard C++ Library */
- /* Name......: New.cp */
- /* Purpose...: standard C++ library */
- /* Copyright.: ©Copyright 1994 by metrowerks inc. All rights reserved. */
- /************************************************************************/
-
- #include <new.h>
- #include <Memory.h>
-
- #pragma a6frames on
-
- #define NEWMODE NEWMODE_FAST // mode used to compile this file
-
- #define NEWMODE_NONE 0 // do not define operator new/delete
- #define NEWMODE_SIMPLE 1 // call NewPtr/DisposPtr
- #define NEWMODE_MALLOC 2 // use malloc/free
- #define NEWMODE_NORMAL 3 // regular new/delete
- #define NEWMODE_FAST 4 // regular new/delete fast version
-
- #define NEWMODE_NORMAL_FASTFREE 0 // NEWMODE_NORMAL faster free (real bad fragmentation)
-
- // These macros are allow DebugNew.cp to redefine operators
- // new and delete in debug mode while not adding any overhead
- // for the non-debug case.
-
- #ifndef OPERATOR_NEW
- #define OPERATOR_NEW operator new
- #endif
- #ifndef OPERATOR_DELETE
- #define OPERATOR_DELETE operator delete
- #endif
-
- extern void (*new_handler)();
-
- #if NEWMODE==NEWMODE_SIMPLE
-
- /************************************************************************/
- /* Purpose..: Allocate memory */
- /* Input....: size of memory to allocate */
- /* Return...: pointer to memory or 0L */
- /************************************************************************/
- void *OPERATOR_NEW(size_t /* size */,void *p)
- {
- return p;
- }
-
- /************************************************************************/
- /* Purpose..: Allocate memory */
- /* Input....: size of memory to allocate */
- /* Return...: pointer to memory or 0L */
- /************************************************************************/
- void *OPERATOR_NEW(size_t size)
- {
- void *ptr;
-
- while((ptr=NewPtr(size))==NULL)
- {
- if(new_handler) new_handler(); else return(NULL);
- }
- return(ptr);
- }
-
- /************************************************************************/
- /* Purpose..: Dispose memory */
- /* Input....: pointer to memory or 0L (no action if 0L) */
- /* Return...: --- */
- /************************************************************************/
- void OPERATOR_DELETE(void *ptr)
- {
- if(ptr) DisposPtr((Ptr)ptr);
- }
-
- #elif NEWMODE==NEWMODE_MALLOC
-
- #include <stdlib.h>
-
- /************************************************************************/
- /* Purpose..: Allocate memory */
- /* Input....: size of memory to allocate */
- /* Return...: pointer to memory or 0L */
- /************************************************************************/
- void *OPERATOR_NEW(size_t /* size */,void *p)
- {
- return p;
- }
-
- /************************************************************************/
- /* Purpose..: Allocate memory */
- /* Input....: size of memory to allocate */
- /* Return...: pointer to memory or 0L */
- /************************************************************************/
- void *OPERATOR_NEW(size_t size)
- {
- void *ptr;
-
- while((ptr=malloc(size))==NULL)
- {
- if(new_handler) new_handler(); else return(NULL);
- }
- return(ptr);
- }
-
- /************************************************************************/
- /* Purpose..: Dispose memory */
- /* Input....: pointer to memory or 0L (no action if 0L) */
- /* Return...: --- */
- /************************************************************************/
- void OPERATOR_DELETE(void *ptr)
- {
- free(ptr);
- }
-
- #elif NEWMODE==NEWMODE_NORMAL
-
- typedef struct FreeMemList {
- struct FreeMemList *next;
- long size;
- } FreeMemList;
-
- static FreeMemList memlist; // dummy header block (always empty)
- static size_t _newpoolsize = 0x00010000L; // number of bytes allocated for a new pool
- static size_t _newnonptrmax = 0x00001000L; // any object bigger than this will call NewPtr(...) directly
-
- /************************************************************************/
- /* Purpose..: Set size of future allocation pools */
- /* Input....: size of future allocation pools */
- /* Return...: --- */
- /************************************************************************/
- void _set_newpoolsize(size_t size)
- {
- _newpoolsize=size;
- }
-
- /************************************************************************/
- /* Purpose..: Set NewPtr(...) pointer threshold */
- /* Input....: size of new threshold */
- /* Return...: --- */
- /************************************************************************/
- void _set_newnonptrmax(size_t size)
- {
- _newnonptrmax=size;
- }
-
- /************************************************************************/
- /* Purpose..: Preallocate an allocation pool */
- /* Input....: size of pool to allocate */
- /* Return...: 1: no error; 0: fail */
- /************************************************************************/
- char _prealloc_newpool(size_t size)
- {
- FreeMemList *list;
-
- if((list=(FreeMemList *)NewPtr(size))==NULL) return 0;
- list->next=memlist.next; list->size=size; memlist.next=list;
- return 1;
- }
-
- /************************************************************************/
- /* Purpose..: Allocate memory */
- /* Input....: size of memory to allocate */
- /* Return...: pointer to memory or 0L */
- /************************************************************************/
- void *OPERATOR_NEW(size_t /* size */,void *p)
- {
- return p;
- }
-
- /************************************************************************/
- /* Purpose..: Allocate memory */
- /* Input....: size of memory to allocate */
- /* Return...: pointer to memory or 0L */
- /************************************************************************/
- void *OPERATOR_NEW(size_t size)
- {
- Ptr ptr;
-
- size=(size&0xFFFFFFFC)+8; // alloc *4 quantity plus 4 extra bytes for size
-
- if(size>=_newnonptrmax)
- { // try to get pointer from OS
- while(1)
- {
- if((ptr=NewPtr(size))!=NULL) { *(long *)ptr=-1L; return(ptr+4); }
- if(new_handler) new_handler(); else return(NULL);
- }
- }
-
- while(1)
- {
- FreeMemList *list,*prev;
-
- for(prev=&memlist,list=prev->next; list; prev=list,list=list->next) if(size<=list->size)
- {
- alloc: if(list->size>=size+sizeof(FreeMemList))
- { // split this free block
- list->size-=size; ptr=(Ptr)list+list->size;
- *(long *)ptr=size; return(ptr+4);
- }
- // remove this block from list
- prev->next=list->next; *(long *)list=list->size; return((Ptr)list+4);
- }
-
- // not enough free memory in memlist (try to allocate a new Ptr from OS
- if((list=(FreeMemList *)NewPtr(_newpoolsize))==NULL)
- { // try to allocate a system block
- if((ptr=NewPtr(size))!=NULL) { *(long *)ptr=-1L; return(ptr+4); }
- if(new_handler) new_handler(); else return(NULL);
- }
- else
- {
- list->next=memlist.next; list->size=_newpoolsize;
- memlist.next=list; prev=&memlist; goto alloc;
- }
- }
- }
-
- /************************************************************************/
- /* Purpose..: Dispose memory */
- /* Input....: pointer to memory or 0L (no action if 0L) */
- /* Return...: --- */
- /************************************************************************/
- void OPERATOR_DELETE(void *ptr)
- {
- if(ptr)
- {
- long size;
-
- ptr=(Ptr)ptr-4; size=*(long *)ptr;
- if(size!=-1L)
- {
- FreeMemList *list;
- #if !NEWMODE_NORMAL_FASTFREE
- FreeMemList *prev;
- char merge=0;
-
- for(prev=&memlist,list=prev->next; list; prev=list,list=list->next)
- {
- if((Ptr)ptr+size==(Ptr)list)
- { // merge block in front of this list item
- prev->next=list->next; size+=list->size; list=prev;
- if(merge) break; else { merge=1; continue; }
- }
- if((Ptr)ptr==(Ptr)list+list->size)
- { // merge block at the end of this list item
- prev->next=list->next; ptr=list; size+=list->size; list=prev;
- if(merge) break; else { merge=1; continue; }
- }
- }
- #endif
- list=(FreeMemList *)ptr; list->next=memlist.next; list->size=size; memlist.next=list;
- }
- else DisposPtr((Ptr)ptr);
- }
- }
-
- #elif NEWMODE==NEWMODE_FAST
-
- typedef struct MemPool {
- struct MemPool *next; // pointer to next pool
- size_t size; // number of bytes in pool (including header)
- char data[]; // variable size user data section
- } MemPool;
-
- static MemPool *mempools; // list of memory pools
- static char *lastfree; // pointer to last free block
- static char *lastend; // pointer to last end
- static size_t _newpoolsize = 0x00010000L; // number of bytes allocated for a new pool
- static size_t _newnonptrmax = 0x00001000L; // any object bigger than this will call NewPtr(...) directly
-
- /************************************************************************/
- /* Purpose..: Set size of future allocation pools */
- /* Input....: size of future allocation pools */
- /* Return...: --- */
- /************************************************************************/
- void _set_newpoolsize(size_t size)
- {
- _newpoolsize=size;
- }
-
- /************************************************************************/
- /* Purpose..: Set NewPtr(...) pointer threshold */
- /* Input....: size of new threshold */
- /* Return...: --- */
- /************************************************************************/
- void _set_newnonptrmax(size_t size)
- {
- _newnonptrmax=size;
- }
-
- /************************************************************************/
- /* Purpose..: Preallocate a memory pool */
- /* Input....: size of pool to allocate */
- /* Return...: 1: no error; 0: fail */
- /************************************************************************/
- char _prealloc_newpool(size_t size)
- {
- MemPool *pool;
-
- if((pool=(MemPool *)NewPtr(size))==NULL) return 0;
-
- pool->next=mempools; mempools=pool;
- pool->size=size; *(long *)pool->data=pool->size-sizeof(MemPool);
-
- return 1;
- }
-
- /************************************************************************/
- /* Purpose..: Allocate memory */
- /* Input....: size of memory to allocate */
- /* Return...: pointer to memory or 0L */
- /************************************************************************/
- void *OPERATOR_NEW(size_t /* size */,void *p)
- {
- return p;
- }
-
- /************************************************************************/
- /* Purpose..: Allocate memory */
- /* Input....: size of memory to allocate */
- /* Return...: pointer to memory or 0L */
- /************************************************************************/
- void *OPERATOR_NEW(size_t size)
- {
- MemPool *pool;
- char *ptr,*end;
- long bsize,nsize;
-
- size=(size&0xFFFFFFFC)+8; // alloc *4 quantity plus 4 bytes for size
-
- while(1)
- {
- if(size>=_newnonptrmax && (ptr=(char *)NewPtr(size))!=NULL)
- {
- *(long *)ptr=0L; return ptr+4;
- }
-
- if((ptr=lastfree)!=0L && (bsize=*(long *)ptr)>=(long)size)
- { // last free block has enough memory left
- end=lastend; goto alloc2;
- }
-
- for(pool=mempools; pool; pool=pool->next)
- {
- alloc: for(ptr=pool->data,end=(Ptr)pool+pool->size; ptr<end;) if((bsize=*(long *)ptr)>0)
- {
- alloc2: lastfree=0L;
- while(ptr+bsize<end && (nsize=*(long *)(ptr+bsize))>0)
- { // merge block with the next block
- *(long *)ptr=bsize=bsize+nsize;
- }
- if(bsize>=size)
- { // pool block is big enough
- if(bsize>=size+8)
- { // split this block
- lastfree=ptr; lastend=end;
- bsize-=size; *(long *)ptr=bsize; ptr+=bsize;
- *(long *)ptr=-size; return ptr+4;
- }
- else
- { // allocate whole block
- *(long *)ptr=-bsize; return ptr+4;
- }
- }
- else ptr+=bsize;
- }
- else ptr-=bsize;
- next:; }
-
- // not enough free memory in mempools (try to allocate a new Ptr from OS)
- if((pool=(MemPool *)NewPtr(_newpoolsize))!=NULL)
- {
- pool->next=mempools; mempools=pool;
- pool->size=_newpoolsize; *(long *)pool->data=pool->size-sizeof(MemPool);
- goto alloc;
- }
- else
- { // try to allocate a system block
- if((ptr=(char *)NewPtr(size))!=NULL)
- {
- *(long *)ptr=0L; return ptr+4;
- }
- }
-
- if(new_handler) new_handler(); else return NULL;
- }
- }
-
- /************************************************************************/
- /* Purpose..: Dispose memory */
- /* Input....: pointer to memory or 0L (no action if 0L) */
- /* Return...: --- */
- /************************************************************************/
- void OPERATOR_DELETE(void *ptr)
- {
- if(ptr)
- {
- ptr=(char *)ptr-4;
- if((*(long *)ptr=-*(long *)ptr)==0L) DisposPtr((Ptr)ptr);
- }
- }
-
- #else
-
- // no operator new/delete defined
-
- #endif
-